﻿using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Net;

namespace SystemUpdatesCore.Server.Network
{
    public class NetworkWebClient : INetworkClient
    {
        [AllowNull]
        public string BaseAddress { get; set; }

        /// <summary>
        /// 异步下载文件完成事件
        /// </summary>
        public event AsyncCompletedEventHandler? DownloadFileCompleted;
        /// <summary>
        /// 异步下载文件进度改变事件
        /// </summary>
        public event NetworkDownloadProgressChangedEventHandler? DownloadProgressChanged;

        /// <summary>
        /// 异步获取字符串完成事件
        /// </summary>
        public event NetworkDownloadStringCompletedEventHandler? DownloadStringCompleted;

        public Task DownloadFileTaskAsync(string address, string fileName)
        {
            using (var client = new WebClient())
            {
                client.BaseAddress = BaseAddress;
                client.DownloadProgressChanged += (s, e) => { DownloadProgressChanged?.Invoke(s, new NetworkDownloadProgressChangedEventArgs(e.ProgressPercentage, e.UserState, e.BytesReceived, e.TotalBytesToReceive)); };
                client.DownloadFileCompleted += (s, e) => { DownloadFileCompleted?.Invoke(s, e); };

                return client.DownloadFileTaskAsync(address, fileName);
            }
        }

        /// <summary>
        /// 异步下载文件
        /// </summary>
        /// <param name="address"></param>
        /// <param name="fileName"></param>
        public void DownloadFileAsync(Uri address, string fileName)
        {
            try
            {
                using (var client = new WebClient())
                {
                    client.BaseAddress = BaseAddress;
                    client.DownloadProgressChanged += (s, e) => { DownloadProgressChanged?.Invoke(s, new NetworkDownloadProgressChangedEventArgs(e.ProgressPercentage, e.UserState, e.BytesReceived, e.TotalBytesToReceive)); };
                    client.DownloadFileCompleted += (s, e) => { DownloadFileCompleted?.Invoke(s, e); };

                    client.DownloadFileAsync(address, fileName);
                }
            }
            catch (Exception ex)
            {
                //处理异常
                throw ex;
            }
        }

        /// <summary>
        /// 同步下载文件
        /// </summary>
        /// <param name="address"></param>
        /// <param name="fileName"></param>
        public void DownloadFile(string address, string fileName)
        {
            try
            {
                using (var client = new WebClient())
                {
                    client.BaseAddress = BaseAddress;
                    client.DownloadFile(address, fileName);
                }
            }
            catch (Exception ex)
            {
                //处理异常
                throw ex;
            }
        }

        /// <summary>
        /// 异步获取字符串数据
        /// </summary>
        /// <param name="address"></param>
        public Task<string> DownloadStringTaskAsync(string address)
        {
            using (var client = new WebClient())
            {
                client.BaseAddress = BaseAddress;
                client.DownloadStringCompleted += (s, e) => { DownloadStringCompleted?.Invoke(s, new NetworkDownloadStringCompletedEventArgs(e.Result, e.Error, e.Cancelled, e.UserState)); };
                return client.DownloadStringTaskAsync(address);
            }
        }

        /// <summary>
        /// 异步获取字符串数据
        /// </summary>
        /// <param name="address"></param>
        public void DownloadStringAsync(Uri address)
        {
            using (var client = new WebClient())
            {
                client.BaseAddress = BaseAddress;
                client.DownloadStringCompleted += (s, e) => { DownloadStringCompleted?.Invoke(s, new NetworkDownloadStringCompletedEventArgs(e.Result, e.Error, e.Cancelled, e.UserState)); };
                client.DownloadStringAsync(address);
            }
        }

        /// <summary>
        /// 同步获取字符串数据
        /// </summary>
        /// <param name="address"></param>
        public string DownloadString(string address)
        {
            using (var client = new WebClient())
            {
                client.BaseAddress = BaseAddress;
                return client.DownloadString(address);
            }
        }


    }
}
